Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: EVM changes required to support Solana #672

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open

Conversation

chrismaree
Copy link
Member

@chrismaree chrismaree commented Oct 18, 2024

This is a feature branch where we will place all changes needed to be applied to the EVM to support Solana within across.

This branch contains 4 main categories of changes (each of which was originally a separate PR before moving them into this feature branch):

  1. Change input props & internal data structures within SpokePool.sol to be bytes32. This is a somewhat opinionated change & was done to support bytes32 address types. We also changed internal data structures as it make things easier to reason about.
  2. CCTP <> Solana Adapter. This change facilitates EVM <> SVM communication over CCTP. It contains an amount of wiring to enable the hub (which does not support bytes32, for example) to interface with SVM.
  3. Relayer repayment address as part of fill method. As a relayer will now have a separate address on EVM & SVM, they need the ability to inform the data worker where to be re-paid on the new domain.
  4. Improve how relayer repayments work, supporting blacklisted relayer addresses to not block bundles. Due to change 3, it is now trivial to set a relayer repayment address to a recipient that is blacklisted by the repayment token. If a relayer did this, they would be able to effectively block the whole bundle from being executed. To work around this, a new data structure relayerRefund is added that stores refunds that could not be executed due to reverting transfers. Relayers can then claim these separately, provided they can prove they own the original blocked address.

Reinis-FRP and others added 10 commits October 18, 2024 11:58
* feat(chain-adapters): add solana adapter

Signed-off-by: Reinis Martinsons <[email protected]>

* fix: comments

Signed-off-by: Reinis Martinsons <[email protected]>

* test: solana adapter

Signed-off-by: Reinis Martinsons <[email protected]>

* Update contracts/chain-adapters/Solana_Adapter.sol

Co-authored-by: Chris Maree <[email protected]>

* fix: do not hash bytes32 svm address

Signed-off-by: Reinis Martinsons <[email protected]>

---------

Signed-off-by: Reinis Martinsons <[email protected]>
Co-authored-by: Chris Maree <[email protected]>
* feat: add address to bytes32 contract changes

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: remove todos

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: imports

Signed-off-by: Pablo Maldonado <[email protected]>

* Update contracts/SpokePool.sol

Co-authored-by: Reinis Martinsons <[email protected]>

* feat: bytes 32 comparisons

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: format code

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: tests

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: bytes 32 check

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: ts

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: reuse lib in cctp adapter

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: _preExecuteLeafHook

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: comments

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: _verifyUpdateV3DepositMessage

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: backward compatibility

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: backwards compatibility tests

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: change comparison casting address bytes32

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: test

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: merkle tree leaf to bytes32

Signed-off-by: Pablo Maldonado <[email protected]>

* test: leaf type update fixes

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: remove helper

Signed-off-by: Pablo Maldonado <[email protected]>

---------

Signed-off-by: Pablo Maldonado <[email protected]>
Co-authored-by: Reinis Martinsons <[email protected]>
* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

---------

Signed-off-by: chrismaree <[email protected]>
* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

---------

Signed-off-by: chrismaree <[email protected]>
Signed-off-by: chrismaree <[email protected]>
Signed-off-by: chrismaree <[email protected]>
* @param l2TokenAddress Address of the L2 token to claim refunds for.
* @param refundAddress Address to send the refund to.
*/
function claimRelayerRefund(address l2TokenAddress, address refundAddress) public {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^

@chrismaree chrismaree marked this pull request as ready for review November 5, 2024 15:22
function fillV3Relay(
V3RelayData calldata relayData,
uint256 repaymentChainId,
bytes32 repaymentAddress
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a fillV3Relay overloaded function where the default repayment address is msg.sender? Could this avoid some breaking changes for existing fillers to give them time to migrate to new functions? Or will they already be broken by all the changes in the V3RelayData struct, for example the address -> bytes32 changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the changes in V3RelayData would also be breaking changes, so an update would still be necessary. I’m leaning towards only adding backward compatibility to functions that are called by other contracts, like depositV3.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes in V3Relay might not be as breaking necessarily since address can be implictly converted to bytes32. But I take your point.

@pxrl wdyt about this?

// prevents can only re-pay some of the relayers.
if (totalRefundedAmount > spokeStartBalance) revert InsufficientSpokePoolBalanceToExecuteLeaf();

bool success = _noRevertTransfer(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pxrl how much lift do you think there will be for the executor to deal with this change where refunds can now fail?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that they dont fail. the behaviour is more kind to the executor. in a very rare event where you set a blacklisted recipient in the transfer then the recipient gets a credit they can claim. the design here should require no additional changes to the executor. we should, however, listen to events that indicate if this has happened.

totalRefundedAmount += refundAmounts[i];

// Only if the total refunded amount exceeds the spoke starting balance, should we revert. This
// ensures that bundles are atomic, if we have sufficient balance to refund all relayers and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for reverting here, as this is a common failure path where a spoke pool is missing funds due to some out of protocol issue like a l1->l2 token transfer via canonical bridge failing

updatedRecipient.toBytes32(),
updatedMessage,
depositorSignature,
UPDATE_V3_DEPOSIT_ADDRESS_OVERLOAD_DETAILS_HASH
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the hash need to be different?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because, when adding backwards compatibility to speedUpV3Deposit with the address version, we still need to support an updatedMessage constructed with the old data type. Maybe this is unnecessary?

I was assuming that there might be cases were contracts are calling this speedUpV3Deposit with the old signature and thus passing updatedMessage built with the old data structure

However if speedUpV3Deposit is only expected to be called off-chain we probably don't need backwards compatibility and can drop UPDATE_V3_DEPOSIT_ADDRESS_OVERLOAD_DETAILS_HASH.

Can you pls clarify how is speedUpV3Deposit is used @nicholaspai ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was assuming that there might be cases were contracts are calling this speedUpV3Deposit with the old signature

Yeah this is possible for a short time after the contracts are upgraded, but long-term there will be no more speedUpV3Deposit calls with the old signature so we can actually mark this old signature as something to remove in the future

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However if speedUpV3Deposit is only expected to be called off-chain

What do you mean by off-chain?

Can you pls clarify how is speedUpV3Deposit is used @nicholaspai ?

The way this is used is a depositor sees a speed up button on the FE which prompts them to sign a message which they then submit to speedUpV3Deposit, code here

* @param l2TokenAddress Address of the L2 token to claim refunds for.
* @param refundAddress Address to send the refund to.
*/
function claimRelayerRefund(address l2TokenAddress, address refundAddress) public {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I see refundAddress is type address, and the relayerRefund mapping also uses an address=>address key. This is because these variables are only used on the chain that this spoke pool would be deployed to, which will always be an EVM?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can migrate this to bytes32 as well to be consistent with the rest of updates. What do you think @chrismaree?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree for consistency it should be moved over. doing it now & updating the tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have updated this accordingly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there any storage/gas cost considerations to think about with this change?

_transferUsdc(SOLANA_SPOKE_POOL_USDC_VAULT, amount);

// TODO: consider if we need also to emit the translated addresses.
emit TokensRelayed(l1Token, l2Token, amount, to);
Copy link
Member

@nicholaspai nicholaspai Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could be useful to emit the translated addresses at very little additional marginal cost

}

bytes4 selector = bytes4(message[:4]);
if (selector == SpokePoolInterface.setEnableRoute.selector) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is setEnableRoute a specific case here? Is it the only function we'll be calling on the Solana spoke pool? For example, does this prevent us from pausing deposits/fills, emergency deleting root bundles, or forcing through admin root bundles? These haven't really happened. much in the past but the latter two have happened at least once

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep the address version of setEnableRoute for backward compatibility with the hub pool, and that specific handler translates the message to the bytes32 version.

@Reinis-FRP, do you remember why we decided to handle the translation here, which led us to do the casting here instead of handling it in SVM?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason is that setEnableRoute is invoked via setDepositRoute on HubPool that we are not upgrading and we need different types on Solana. For other admin methods they are crafted manually and bridged via generic relaySpokePoolAdminFunction method, so the operator can adjust the interface types for all other methods to Solana.

Copy link
Contributor

@md0x md0x Nov 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But @Reinis-FRP , couldn’t this conversion also be handled on the svm side? We initially chose to implement it here, but after thinking it over, I agree with @mrice32 that it might make more sense to handle this directly within the solana specific implementation. Also, @mrice32 pointed out a similar approach for Arbitrum in this comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be bit tricky as we would need to pass mapping account that stores address translation when receiving the message on Solana side. It does not really belong under HandleReceiveMessage which translates all other supported admin calls statelessly. And if we move the address translation account down to self-invoked SetEnableRoute then we would end up changing the interface of set_enable_route to use [u8; 20] as its origin_token parameter, which is not ideal as we also support calling it from Solana admin (or need to implement both flavors). And this also requires additional admin method to update the mapping account with correct address translation.

Not saying its impossible to do, but it seemed to have less code complexity if we move the translation to the adapter on EVM side, especially, since it already needs to translate trimmed Solana USDC address to its vault associated token account anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it sounds like the tradeoff here is (less code complexity, special case for setEnableDepositRoute on the EVM side, generic SVM side logic) versus (more code complexity, but totally generic EVM logic and bespoke SVM side logic), right? What about gas costs?

Copy link
Member

@nicholaspai nicholaspai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is very clean, amazing work that you all should be very happy with. I left some questions and will take a second pass once we go through them all

Copy link
Contributor

@mrice32 mrice32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks awesome! Left a few questions to start. Still working my way through

@@ -67,7 +70,7 @@ abstract contract SpokePool is
RootBundle[] public rootBundles;

// Origin token to destination token routings can be turned on or off, which can enable or disable deposits.
mapping(address => mapping(uint256 => bool)) public enabledDepositRoutes;
mapping(bytes32 => mapping(uint256 => bool)) public enabledDepositRoutes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to convert this to bytes32? Isn't this mapping from an origin chain token (which will always be a 20 byte address)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that all the arguments have been moved to bytes32-- a decision that you can challenge as well--this made sense from a consistency perspective. We also decided to emit all addresses in their bytes32 form, so keeping the address representation here would require extra casting. Does this make sense @mrice32 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ye, there is an overall design here to make everything bytes32 internally this makes reasoning about data structures and props easier and more consistent as its always bytes32. we could in theory change this accordingly such that we treat all evm data as address type and type cast as soon as possible when entering methods with bytes32. very much opinonated, very much can be changed if you'll prefer the other option.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is an overall design here to make everything bytes32 internally

I think this is correct directionally

function depositV3Now(
bytes32 depositor,
bytes32 recipient,
bytes32 inputToken,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interface design question: if we know this token is local (and therefore an address), is there a point in making it bytes32?

Same question for depositor.

There may be an advantage in keeping them consistent, but there is a disadvantage in validation/error cases: it's possible to pass in bytes32 addresses that do not correspond to a valid local address.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason was consistency with the rest of the data. We still have the overloaded versions of these functions that can help with the validation/casting of addresses.

We have tried to move everything to bytes32 in this contract. While in the short term there might be a bit of friction, I think in the medium term it’s better to have everything in either bytes32 or address, but not mixed, as mixing is more error-prone. However, we have made these changes somewhat radically and are looking for your feedback.

We do have bytes32 address encoding checks

if (uint256(_bytes32) >> 192 != 0) {
revert InvalidBytes32();
}
to partially help with the address to bytes32 conversion.

Comment on lines 619 to 633
depositV3(
depositor.toBytes32(),
recipient.toBytes32(),
inputToken.toBytes32(),
outputToken.toBytes32(),
inputAmount,
outputAmount,
destinationChainId,
exclusiveRelayer.toBytes32(),
quoteTimestamp,
fillDeadline,
exclusivityPeriod,
message
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think we may want to consider just forwarding the raw msg.data to the other function via a self delegatecall. I think this would be cheaper and less bytecode (although I could be wrong).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into this and report back.

Copy link
Member Author

@chrismaree chrismaree Nov 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I played with this for a few hours and think that the msg.data + self delegate call is overly complex and not worth it. I did something like this:

fallback() external payable {
        // Extract the function selector
        bytes4 selector;
        assembly {
            selector := calldataload(0)
        }

        // Check if selector matches `depositV3(address, address, address, address, uint256, uint256, uint256, address, uint32, uint32, uint32, bytes)`
        if (
            selector ==
            bytes4(
                keccak256(
                    "depositV3(address,address,address,address,uint256,uint256,uint256,address,uint32,uint32,uint32,bytes)"
                )
            )
        ) {
            // Extract each address parameter and cast to bytes32
            bytes32 depositor;
            bytes32 recipient;
            bytes32 inputToken;
            bytes32 outputToken;
            bytes32 exclusiveRelayer;

            // Using assembly for efficient calldata extraction and casting
            // Using assembly for efficient calldata extraction and conversion
            assembly {
                depositor := shl(96, calldataload(4)) // address -> bytes32
                recipient := shl(96, calldataload(36)) // address -> bytes32
                inputToken := shl(96, calldataload(68)) // address -> bytes32
                outputToken := shl(96, calldataload(100)) // address -> bytes32
                exclusiveRelayer := shl(96, calldataload(228)) // address -> bytes32
            }

            // Load other uint256 and uint32 values from calldata directly
            uint256 inputAmount;
            uint256 outputAmount;
            uint256 destinationChainId;
            uint32 quoteTimestamp;
            uint32 fillDeadline;
            uint32 exclusivityPeriod;
            bytes memory message;

            // Directly load the rest of the parameters from calldata
            assembly {
                inputAmount := calldataload(132)
                outputAmount := calldataload(164)
                destinationChainId := calldataload(196)
                quoteTimestamp := calldataload(260)
                fillDeadline := calldataload(292)
                exclusivityPeriod := calldataload(324)
            }

            // uint256 messageStart = 356; // Correct starting position for message
            // uint256 messageLength = msg.data.length > messageStart ? msg.data.length - messageStart : 0;

            // Copy `message` data directly
            // message = new bytes(messageLength);
            // if (messageLength > 0) {
            //     for (uint i = 0; i < messageLength; i++) {
            //         message[i] = msg.data[messageStart + i];
            //     }
            // }
            message = new bytes(0);

            // Forward the call to `depositV3(bytes32, bytes32, bytes32, bytes32, uint256, uint256, uint256, bytes32, uint32, uint32, uint32, bytes)
            (bool success, ) = address(this).delegatecall(
                abi.encodeWithSelector(
                    this.depositV3.selector,
                    depositor,
                    recipient,
                    inputToken,
                    outputToken,
                    inputAmount,
                    outputAmount,
                    destinationChainId,
                    exclusiveRelayer,
                    quoteTimestamp,
                    fillDeadline,
                    exclusivityPeriod,
                    message
                )
            );
            require(success, "Delegatecall to depositV3 failed");
        } else {
            // Handle unexpected calls
            revert("Function selector not supported");
        }
    }

(note the message decoding is broken so I hard coded it to bytes 0).

this works. but:

  1. it's more expensive than the wrapped version (marginally, but still more).
  2. it was super irritating to implement,
  3. it makes our ABIs a massive pain to work with (we need a custom interface in the build process to append this to the ABI as we no longer have public functions exposing them

is this the kind of thing you were envisioning? I think if this is the pattern we need to go for then I'm a strong proponent of the much easier version that the PR has rn.

*/

// solhint-disable-next-line contract-name-camelcase
contract Solana_Adapter is AdapterInterface, CircleCCTPAdapter {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much of this contract is specific to Solana vs could be used with any chain we connect to via CCTP?

I haven't gone deep on the specifics, but, for instance, can we build an adapter that could be used just as well with an EVM chain like BSC?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is quite specific in a sense that it must be aware of Solana token model where recipient SpokePool address needs to be translated to its corresponding vault token address.

contracts/erc7683/ERC7683.sol Outdated Show resolved Hide resolved
contracts/erc7683/ERC7683.sol Outdated Show resolved Hide resolved
contracts/erc7683/ERC7683Across.sol Outdated Show resolved Hide resolved
Comment on lines +185 to +191
return
abi.encodeWithSignature(
"setEnableRoute(bytes32,uint64,bool)",
SOLANA_USDC_BYTES32,
uint64(destinationChainId),
enable
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OOC, why not do this mapping on the Solana side?

In theory, could we not have a mapping (from truncated address to full address) exist on the Solana side that could be modified by an admin call. Then, the flow to add a new token would require no contract changes:

  1. Send admin call to update the mapping with a new element.
  2. Add the route to use the newly added element.

Side note: this is somewhat similar to something we have to do on arbitrum.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need to map truncated USDC address to Solana spoke pool vault here to support relayTokens method used when rebalancing from HubPool to Solana spoke via CCTP token bridge. So if we were to add new token we would anyways need to redeploy the adapter, hence it is easier to keep all related aliasing contained in this contract.

@md0x md0x added the do not merge do not merge label Nov 7, 2024
md0x and others added 30 commits November 19, 2024 17:22
* refactor(svm): reuse bytes32 to address lib in svm adapter

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: custom errors

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: fix test

Signed-off-by: Pablo Maldonado <[email protected]>

---------

Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: chrismaree <[email protected]>
Signed-off-by: chrismaree <[email protected]>
Signed-off-by: chrismaree <[email protected]>
Signed-off-by: chrismaree <[email protected]>
This function was used to express exclusivity as a period but its no longer useful since depositV3 now allows caller to express exclusivityPeriod instead of exclusivityDeadline
* Revert "feat(SpokePool): Introduce opt-in deterministic relay data hashes (#583)"

This reverts commit 9d21d1b.

* Reapply "feat(SpokePool): Introduce opt-in deterministic relay data hashes (#583)"

This reverts commit d363bf0.

* add deposit nonces to 7683

Signed-off-by: Matt Rice <[email protected]>

* fix

Signed-off-by: Matt Rice <[email protected]>

* WIP

Signed-off-by: Matt Rice <[email protected]>

* feat(SpokePool): Introduce opt-in deterministic relay data hashes (#583)

* fix(SpokePool): Apply exclusivity consistently

The new relative exclusivity check has not been propagated to
fillV3RelayWithUpdatedDeposit(). Identified via test case failures in
the relayer.

Signed-off-by: Paul <[email protected]>

* Also check on slow fill requests

* Update contracts/SpokePool.sol

* lint

* Update

* Add pure

* Fix

* Add tests

* improve(SpokePool): _depositV3 interprets `exclusivityParameter` as 0, an offset, or a timestamp

There should be a way for the deposit transaction to remove chain re-org risk affecting the block.timestamp by allowing the caller to set a fixed `exclusivityDeadline` value. This supports the existing behavior where the `exclusivityDeadline` is always emitted as its passed in.

The new behavior is that if the `exclusivityParameter`, which replaces the `exclusivityDeadlineOffset` parameter, is 0 or greater than 1 year in seconds, then the `exclusivityDeadline` is equal to this parameter. Otherwise, its interpreted by `_depositV3()` as an offset. The offset would be useful in cases where the origin chain will not re-org, for example.

* Update SpokePool.sol

* Update SpokePool.Relay.ts

* Update SpokePool.SlowRelay.ts

* Update contracts/SpokePool.sol

Co-authored-by: Paul <[email protected]>

* Update SpokePool.sol

* Update contracts/SpokePool.sol

* rebase

* Update SpokePool.sol

* Revert "Merge branch 'npai/exclusivity-switch' into mrice32/deterministic-new"

This reverts commit 2432944, reversing
changes made to 6fe3534.

* Revert "Merge branch 'npai/exclusivity-switch' into mrice32/deterministic-new"

This reverts commit 2432944, reversing
changes made to 6fe3534.

* revert

* Update SpokePool.sol

* Fix

* Update SpokePool.sol

Co-authored-by: Chris Maree <[email protected]>

* WIP

* WIP

* wip

* Update SpokePool.Relay.ts

* Fix

* Update SpokePool.sol

* Update SpokePool.sol

---------

Signed-off-by: Matt Rice <[email protected]>
Signed-off-by: Paul <[email protected]>
Co-authored-by: nicholaspai <[email protected]>
Co-authored-by: nicholaspai <[email protected]>
Co-authored-by: Paul <[email protected]>
Co-authored-by: Chris Maree <[email protected]>
* fix: emit hashed message in evm fill events

Signed-off-by: Reinis Martinsons <[email protected]>

* WIP

Signed-off-by: chrismaree <[email protected]>

* fix: linting

Signed-off-by: Reinis Martinsons <[email protected]>

---------

Signed-off-by: Reinis Martinsons <[email protected]>
Signed-off-by: chrismaree <[email protected]>
Co-authored-by: chrismaree <[email protected]>
Signed-off-by: Reinis Martinsons <[email protected]>
Signed-off-by: Reinis Martinsons <[email protected]>
Signed-off-by: chrismaree <[email protected]>
Signed-off-by: chrismaree <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge do not merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants